package vip.xiaonuo.common.aspect;

import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.net.InetAddress;
import java.util.List;
import java.util.Properties;

@Aspect
@Component
@Slf4j
public class InstanceOnlineAspect {

    @Value("${spring.application.name}")
    private String serviceName;

    @Value("${spring.nacos.server}")
    private String serverAddr;

    @Value("${spring.cloud.nacos.discovery.namespace}")
    private String namespace;

    @Value("${spring.profiles.active}")
    private String active;

    @Value("${spring.nacos.username}")
    private String username;

    @Value("${spring.nacos.password}")
    private String password;

    @Value("${server.port}")
    private int localPort;

    private NamingService namingService;

    @PostConstruct
    public void init() throws NacosException {
        Properties properties = new Properties();
        properties.put("serverAddr", serverAddr);
        properties.put("namespace", namespace);
        properties.put("username", username);
        properties.put("password", password);
        try {
            namingService = NacosFactory.createNamingService(properties);
            log.info("Nacos命名服务初始化成功，Namespace: {}", namespace);
        } catch (NacosException e) {
            log.error("Nacos初始化失败: ", e);
            throw e;
        }
    }

    @Around("@annotation(vip.xiaonuo.common.annotation.CommonCheckInstanceOnline)")
    public Object checkServiceStatus(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        String methodName = methodSignature.getMethod().getName();
        String localIp = InetAddress.getLocalHost().getHostAddress();
        // 使用注入的端口
        int port = this.localPort;
        log.info("检查服务状态，IP: {}，端口: {}", localIp, port);
        List<Instance> instances = namingService.getAllInstances(serviceName, active);
        log.info("服务实例列表: {}", instances.size());
        boolean isServiceOnline = instances.stream()
                .anyMatch(instance ->
                        instance.getIp().equals(localIp) &&
                                instance.getPort() == port &&
                                instance.isHealthy()
                );
        if (!isServiceOnline) {
            log.error("服务未在线，方法 {} 被阻止执行。", methodName);
            return null;
        }
        return joinPoint.proceed();
    }
}
